/*
 * Copyright 2020-2025 the original author or authors.
 * You cannot use this file unless authorized by the author.
 */
package org.ipig.commons.helper;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.IllegalClassException;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Collection
 *
 * @author <a href="mailto:comchnts@163.com">chinats</a>
 * @version $$Id: CollectionHelper.java 14 2020-04-17 06:56:19Z ts <comchnts@163.com> $$
 * @since 1.0
 */
public class CollectionHelper {

    /**
     * partition
     *
     * @param inList
     * @param partition
     * @param <T>
     * @return
     */
    public static <T> List<List<T>> partition(List<T> inList, int partition) {
        List<List<T>> lists = new ArrayList<List<T>>();
        if (inList == null || inList.size() < 2 || partition < 2) {
            lists.add(inList);
        } else {
            int inSize = inList.size();
            int batch = inSize / partition;
            batch = (batch <= 0) ? 1 : batch;
            int beginIndex = 0;
            int endIndex = 0;
            for (int i = 0; i < partition - 1 && beginIndex < inSize; i++) {
                endIndex = Math.min(inSize, beginIndex + batch);
                lists.add(inList.subList(beginIndex, endIndex));
                beginIndex += endIndex - beginIndex;
            }
            if (beginIndex < inSize) {
                lists.add(inList.subList(beginIndex, inSize));
            }
        }
        return lists;
    }

    /**
     * JSONObjectMerge
     *
     * @param oldMap
     * @param newMap
     * @throws IllegalClassException
     */
    public static void JSONObjectMerge(Map oldMap, Map newMap) throws IllegalClassException {
        for (Object key : newMap.keySet()) {
            if (oldMap.containsKey(key)) {
                Object oldObj = oldMap.get(key);
                Object newObj = newMap.get(key);
                if (oldObj instanceof Map && newObj instanceof Map) {
                    JSONObjectMerge((Map) oldObj, (Map) newObj);
                    continue;
                }
                if (oldObj instanceof List && newObj instanceof List) {
                    ((List) oldObj).addAll((List) newObj);
                    continue;
                }
                throw new IllegalClassException(new StringBuilder().append("Confilct Key:" + key.toString())
                        .append("Confilct Type:" + oldObj.getClass().toString() + "<=>" + newObj.getClass().toString())
                        .toString());
            }
            oldMap.put(key, newMap.get(key));
        }
    }

    /**
     * initOrGetNextMap
     *
     * @param map
     * @param key
     * @param clazz
     * @param <T>
     * @return
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    public static <T> T initOrGetNextMap(Map<String, Object> map, String key, Class<T> clazz) throws IllegalAccessException, InstantiationException {
        if (!map.containsKey(key)) {
            T value = (T) clazz.newInstance();
            map.put(key, value);
            return value;
        }
        return (T) map.get(key);
    }

    /**
     * initOrGetNextJsonObj
     *
     * @param jsonObj
     * @param key
     * @param clazz
     * @param <T>
     * @return
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    public static <T> T initOrGetNextJsonObj(JSONObject jsonObj, String key, Class<T> clazz) throws IllegalAccessException, InstantiationException {
        if (!jsonObj.containsKey(key)) {
            T value = (T) clazz.newInstance();
            jsonObj.put(key, value);
            return value;
        }
        return (T) jsonObj.get(key);
    }
}